//
// Created by f12160c on 2018/7/25.
//

#include <iostream>
#include <vector>
#include<gtest/gtest.h>

#include "leetcode/leetcode.hpp"

using namespace std;

namespace {
    bool compare_vector_list(vector<int> & x, vector<int> &y)
    {
        if(x[0] < y[0])
        {
            return true;
        }
        else if(x[0] == y[0])
        {
            if(x[1] < y[1])
            {
                return true;
            }
            else if(x[1] == y[1])
            {
                if(x[2] < y[2])
                {
                    return true;
                }
                else if(x[2] == y[2])
                {
                    return x[3] < y[3];
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    TEST(test_fourSum, 1) {
        vector intput = { 1, 0, -1, 0, -2, 2};
        vector<vector<int>> expect_output = { {-2, -1, 1, 2}, {-2, 0, 0 ,2}, {-1, 0, 0, 1} };

        auto acture_output = Solution::fourSum(intput, 0);
        ASSERT_EQ(expect_output.size(), acture_output.size());

        for(auto elm: acture_output)
        {
            sort(elm.begin(), elm.end());
        }
        sort(acture_output.begin(), acture_output.end(), compare_vector_list);

        for(int i = 0; i < acture_output.size(); i++)
        {
            ASSERT_EQ(expect_output[i], acture_output[i]);
        }
    }

    TEST(test_fourSum, 2) {
        vector intput = { -3, -2, -1, 0, 0, 1, 2, 3};
        vector<vector<int>> expect_output = {{-3,-2,2,3},{-3,-1,1,3},{-3,0,0,3},{-3,0,1,2},{-2,-1,0,3},{-2,-1,1,2},{-2,0,0,2},{-1,0,0,1}};

        auto acture_output = Solution::fourSum(intput, 0);
        ASSERT_EQ(expect_output.size(), acture_output.size());

        for(auto elm: acture_output)
        {
            sort(elm.begin(), elm.end());
        }
        sort(acture_output.begin(), acture_output.end(), compare_vector_list);

        for(int i = 0; i < acture_output.size(); i++)
        {
            ASSERT_EQ(expect_output[i], acture_output[i]);
        }
    }

    TEST(test_fourSum, 3) {
        vector intput = {-5,-4,-3,-2,-1,0,0,1,2,3,4,5};
        vector<vector<int>> expect_output = {{-5,-4,4,5},{-5,-3,3,5},{-5,-2,2,5},{-5,-2,3,4},{-5,-1,1,5},{-5,-1,2,4},
                                                {-5,0,0,5},{-5,0,1,4},{-5,0,2,3},{-4,-3,2,5},{-4,-3,3,4},{-4,-2,1,5},
                                                {-4,-2,2,4},{-4,-1,0,5},{-4,-1,1,4},{-4,-1,2,3},{-4,0,0,4},{-4,0,1,3},
                                                {-3,-2,0,5},{-3,-2,1,4},{-3,-2,2,3},{-3,-1,0,4},{-3,-1,1,3},
                                                {-3,0,0,3},{-3,0,1,2},{-2,-1,0,3},{-2,-1,1,2},{-2,0,0,2},{-1,0,0,1}};

        auto acture_output = Solution::fourSum(intput, 0);

        ASSERT_EQ(expect_output.size(), acture_output.size());

        for(auto elm: acture_output)
        {
            sort(elm.begin(), elm.end());
        }
        sort(acture_output.begin(), acture_output.end(), compare_vector_list);

        for(int i = 0; i < acture_output.size(); i++)
        {
            ASSERT_EQ(expect_output[i], acture_output[i]);
        }
    }

    TEST(test_fourSum, 4) {
        vector intput = {-5,5,4,-3,0,0,4,-2};
        vector<vector<int>> expect_output = {{-5,0,4,5},{-3,-2,4,5}};

        auto acture_output = Solution::fourSum(intput, 4);

        ASSERT_EQ(expect_output.size(), acture_output.size());

        for(auto elm: acture_output)
        {
            sort(elm.begin(), elm.end());
        }
        sort(acture_output.begin(), acture_output.end(), compare_vector_list);

        for(int i = 0; i < acture_output.size(); i++)
        {
            ASSERT_EQ(expect_output[i], acture_output[i]);
        }
    }

    TEST(test_fourSum, 5) {
        vector intput = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5};
        vector<vector<int>> expect_output = {{1, 2, 3, 4}};

        auto acture_output = Solution::fourSum(intput, 10);

        ASSERT_EQ(expect_output.size(), acture_output.size());

        for(auto elm: acture_output)
        {
            sort(elm.begin(), elm.end());
        }
        sort(acture_output.begin(), acture_output.end(), compare_vector_list);

        for(int i = 0; i < acture_output.size(); i++)
        {
            ASSERT_EQ(expect_output[i], acture_output[i]);
        }
    }
}
